home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xlock / flame.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  3.8 KB  |  168 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)flame.c 1.4 91/09/27 XLOCK";
  3. #endif
  4. /*-
  5.  * flame.c - recursive fractal cosmic flames.
  6.  *
  7.  * Copyright (c) 1991 by Patrick J. Naughton.
  8.  *
  9.  * See xlock.c for copying information.
  10.  *
  11.  * Revision History:
  12.  * 27-Jun-91: vary number of functions used.
  13.  * 24-Jun-91: fixed portability problem with integer mod (%).
  14.  * 06-Jun-91: Written. (received from Scott Graves, spot@cs.cmu.edu).
  15.  */
  16.  
  17. #include "xlock.h"
  18. #include <math.h>
  19.  
  20. #define MAXTOTAL    10000
  21. #define MAXBATCH    10
  22. #define MAXLEV        4
  23.  
  24. typedef struct {
  25.     double      f[2][3][MAXLEV];/* three non-homogeneous transforms */
  26.     int         max_levels;
  27.     int         cur_level;
  28.     int         snum;
  29.     int         anum;
  30.     int         width, height;
  31.     int         num_points;
  32.     int         total_points;
  33.     int         pixcol;
  34.     Window      win;
  35.     XPoint      pts[MAXBATCH];
  36. }           flamestruct;
  37.  
  38. static flamestruct flames[MAXSCREENS];
  39.  
  40. static short
  41. halfrandom(mv)
  42.     int         mv;
  43. {
  44.     static short lasthalf = 0;
  45.     unsigned long r;
  46.  
  47.     if (lasthalf) {
  48.     r = lasthalf;
  49.     lasthalf = 0;
  50.     } else {
  51.     r = random();
  52.     lasthalf = r >> 16;
  53.     }
  54.     return r % mv;
  55. }
  56.  
  57. void
  58. initflame(win)
  59.     Window      win;
  60. {
  61.     flamestruct *fs = &flames[screen];
  62.     XWindowAttributes xwa;
  63.  
  64.     srandom(time((long *) 0));
  65.  
  66.     XGetWindowAttributes(dsp, win, &xwa);
  67.     fs->width = xwa.width;
  68.     fs->height = xwa.height;
  69.  
  70.     fs->max_levels = batchcount;
  71.     fs->win = win;
  72.  
  73.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  74.     XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, fs->width, fs->height);
  75.  
  76.     if (Scr[screen].npixels > 2) {
  77.     fs->pixcol = halfrandom(Scr[screen].npixels);
  78.     XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[fs->pixcol]);
  79.     } else {
  80.     XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen));
  81.     }
  82. }
  83.  
  84. static      Bool
  85. recurse(fs, x, y, l)
  86.     flamestruct *fs;
  87.     register double x, y;
  88.     register int l;
  89. {
  90.     int         xp, yp, i;
  91.     double      nx, ny;
  92.  
  93.     if (l == fs->max_levels) {
  94.     fs->total_points++;
  95.     if (fs->total_points > MAXTOTAL)    /* how long each fractal runs */
  96.         return False;
  97.  
  98.     if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) {
  99.         xp = fs->pts[fs->num_points].x = (int) ((fs->width / 2)
  100.                             * (x + 1.0));
  101.         yp = fs->pts[fs->num_points].y = (int) ((fs->height / 2)
  102.                             * (y + 1.0));
  103.         fs->num_points++;
  104.         if (fs->num_points > MAXBATCH) {    /* point buffer size */
  105.         XDrawPoints(dsp, fs->win, Scr[screen].gc, fs->pts,
  106.                 fs->num_points, CoordModeOrigin);
  107.         fs->num_points = 0;
  108.         }
  109.     }
  110.     } else {
  111.     for (i = 0; i < fs->snum; i++) {
  112.         nx = fs->f[0][0][i] * x + fs->f[0][1][i] * y + fs->f[0][2][i];
  113.         ny = fs->f[1][0][i] * x + fs->f[1][1][i] * y + fs->f[1][2][i];
  114.         if (i < fs->anum) {
  115.         nx = sin(nx);
  116.         ny = sin(ny);
  117.         }
  118.         if (!recurse(fs, nx, ny, l + 1))
  119.         return False;
  120.     }
  121.     }
  122.     return True;
  123. }
  124.  
  125.  
  126. void
  127. drawflame(win)
  128.     Window      win;
  129. {
  130.     flamestruct *fs = &flames[screen];
  131.  
  132.     int         i, j, k;
  133.     static      alt = 0;
  134.  
  135.     if (!(fs->cur_level++ % fs->max_levels)) {
  136.     XClearWindow(dsp, fs->win);
  137.     alt = !alt;
  138.     } else {
  139.     if (Scr[screen].npixels > 2) {
  140.         XSetForeground(dsp, Scr[screen].gc,
  141.                Scr[screen].pixels[fs->pixcol]);
  142.         if (--fs->pixcol < 0)
  143.         fs->pixcol = Scr[screen].npixels - 1;
  144.     }
  145.     }
  146.  
  147.     /* number of functions */
  148.     fs->snum = 2 + (fs->cur_level % (MAXLEV - 1));
  149.  
  150.     /* how many of them are of alternate form */
  151.     if (alt)
  152.     fs->anum = 0;
  153.     else
  154.     fs->anum = halfrandom(fs->snum) + 2;
  155.  
  156.     /* 6 coefs per function */
  157.     for (k = 0; k < fs->snum; k++) {
  158.     for (i = 0; i < 2; i++)
  159.         for (j = 0; j < 3; j++)
  160.         fs->f[i][j][k] = ((double) (random() & 1023) / 512.0 - 1.0);
  161.     }
  162.     fs->num_points = 0;
  163.     fs->total_points = 0;
  164.     (void) recurse(fs, 0.0, 0.0, 0);
  165.     XDrawPoints(dsp, win, Scr[screen].gc,
  166.         fs->pts, fs->num_points, CoordModeOrigin);
  167. }
  168.